#include "defines.h"
#include "global.h"

void com_if_filter_cpy(const pel_t *src, int i_src, pel_t *dst, int i_dst, int width, int height)
{
	int row;
	for (row = 0; row < height; row++) {
		memcpy(dst, src, sizeof(pel_t)* width);
		src += i_src;
		dst += i_dst;
	}
}

#define FLT_10TAP_HOR(src, i, coef) ( \
	(src)[i-4] * (coef)[0] + \
	(src)[i-3] * (coef)[1] + \
	(src)[i-2] * (coef)[2] + \
	(src)[i-1] * (coef)[3] + \
	(src)[i  ] * (coef)[4] + \
	(src)[i+1] * (coef)[5] + \
	(src)[i+2] * (coef)[6] + \
	(src)[i+3] * (coef)[7] + \
	(src)[i+4] * (coef)[8] + \
	(src)[i+5] * (coef)[9])

#define FLT_10TAP_VER(src, i, i_src, coef) ( \
	(src)[i-4 * i_src] * (coef)[0] + \
	(src)[i-3 * i_src] * (coef)[1] + \
	(src)[i-2 * i_src] * (coef)[2] + \
	(src)[i-1 * i_src] * (coef)[3] + \
	(src)[i          ] * (coef)[4] + \
	(src)[i+1 * i_src] * (coef)[5] + \
	(src)[i+2 * i_src] * (coef)[6] + \
	(src)[i+3 * i_src] * (coef)[7] + \
	(src)[i+4 * i_src] * (coef)[8] + \
	(src)[i+5 * i_src] * (coef)[9])

#define FLT_6TAP_HOR(src, i, coef) ( \
	(src)[i-2] * (coef)[0] + \
	(src)[i-1] * (coef)[1] + \
	(src)[i  ] * (coef)[2] + \
	(src)[i+1] * (coef)[3] + \
	(src)[i+2] * (coef)[4] + \
	(src)[i+3] * (coef)[5])

#define FLT_6TAP_VER(src, i, i_src, coef) ( \
	(src)[i-2 * i_src] * (coef)[0] + \
	(src)[i-1 * i_src] * (coef)[1] + \
	(src)[i          ] * (coef)[2] + \
	(src)[i+1 * i_src] * (coef)[3] + \
	(src)[i+2 * i_src] * (coef)[4] + \
	(src)[i+3 * i_src] * (coef)[5])

#define FLT_4TAP_HOR(src, i, coef) ( \
	(src)[i - 1] * (coef)[0] + \
	(src)[i    ] * (coef)[1] + \
	(src)[i + 1] * (coef)[2] + \
	(src)[i + 2] * (coef)[3])

#define FLT_4TAP_VER(src, i, i_src, coef) ( \
	(src)[i-1 * i_src] * (coef)[0] + \
	(src)[i          ] * (coef)[1] + \
	(src)[i+1 * i_src] * (coef)[2] + \
	(src)[i+2 * i_src] * (coef)[3])

static void com_if_filter_hor_4(const pel_t *src, int i_src, pel_t *dst, int i_dst, int width, int height, char_t const *coeff, int max_val)
{
	int row, col;
	int sum, val;

	for (row = 0; row < height; row++) {
		for (col = 0; col < width; col++) {
			sum = FLT_4TAP_HOR(src, col, coeff);
			val = (sum + 32) >> 6;
			dst[col] = (pel_t)COM_CLIP3(0, max_val, val);
		}
		src += i_src;
		dst += i_dst;
	}
}

static void com_if_filter_hor_6(const pel_t *src, int i_src, pel_t *dst, int i_dst, int width, int height, char_t const *coeff, int max_val)
{
	int row, col;
	int sum, val;

	for (row = 0; row < height; row++) {
		for (col = 0; col < width; col++) {
			sum = FLT_6TAP_HOR(src, col, coeff);
			val = (sum + 32) >> 6;
			dst[col] = (pel_t)COM_CLIP3(0, max_val, val);
		}
		src += i_src;
		dst += i_dst;
	}
}

static void com_if_filter_hor_10(const pel_t *src, int i_src, pel_t *dst, int i_dst, int width, int height, char_t const *coeff, int max_val)
{
	int row, col;
	int sum, val;

	for (row = 0; row < height; row++) {
		for (col = 0; col < width; col++) {
			sum = FLT_10TAP_HOR(src, col, coeff);
			val = (sum + 32) >> 6;
			dst[col] = (pel_t)COM_CLIP3(0, max_val, val);
		}
		src += i_src;
		dst += i_dst;
	}
}

static void com_if_filter_ver_4(const pel_t *src, int i_src, pel_t *dst, int i_dst, int width, int height, char_t const *coeff, int max_val)
{
	int row, col;
	int sum, val;

	for (row = 0; row < height; row++) {
		for (col = 0; col < width; col++) {
			sum = FLT_4TAP_VER(src, col, i_src, coeff);
			val = (sum + 32) >> 6;
			dst[col] = (pel_t)COM_CLIP3(0, max_val, val);
		}
		src += i_src;
		dst += i_dst;
	}
}

static void com_if_filter_ver_6(const pel_t *src, int i_src, pel_t *dst, int i_dst, int width, int height, char_t const *coeff, int max_val)
{
	int row, col;
	int sum, val;

	for (row = 0; row < height; row++) {
		for (col = 0; col < width; col++) {
			sum = FLT_6TAP_VER(src, col, i_src, coeff);
			val = (sum + 32) >> 6;
			dst[col] = (pel_t)COM_CLIP3(0, max_val, val);
		}
		src += i_src;
		dst += i_dst;
	}
}

static void com_if_filter_ver_10(const pel_t *src, int i_src, pel_t *dst, int i_dst, int width, int height, char_t const *coeff, int max_val)
{
	int row, col;
	int sum, val;

	for (row = 0; row < height; row++) {
		for (col = 0; col < width; col++) {
			sum = FLT_10TAP_VER(src, col, i_src, coeff);
			val = (sum + 32) >> 6;
			dst[col] = (pel_t)COM_CLIP3(0, max_val, val);
		}
		src += i_src;
		dst += i_dst;
	}
}

static void com_if_filter_hor_ver_4(const pel_t *src, int i_src, pel_t *dst, int i_dst, int width, int height, const char_t *coeff_h, const char_t *coeff_v, int max_val)
{
	int row, col;
	int sum, val;
	int add1, shift1;
	int add2, shift2;

	ALIGNED_16(i16s_t tmp_res[(32 + 3) * 32]);
	i16s_t *tmp;

	shift1 = 0;
	shift2 = 12;

	add1 = (1 << (shift1)) >> 1;
	add2 = 1 << (shift2 - 1);

	src += -1 * i_src;
	tmp = tmp_res;

	for (row = -1; row < height + 2; row++) {
		for (col = 0; col < width; col++) {
			tmp[col] = FLT_4TAP_HOR(src, col, coeff_h);
		}
		src += i_src;
		tmp += 32;
	}

	tmp = tmp_res + 1 * 32;

	for (row = 0; row < height; row++) {
		for (col = 0; col < width; col++) {
			sum = FLT_4TAP_VER(tmp, col, 32, coeff_v);
			val = (sum + add2) >> shift2;
			dst[col] = COM_CLIP3(0, max_val, val);
		}
		dst += i_dst;
		tmp += 32;
	}
}


static void com_if_filter_hor_ver_6(const pel_t *src, int i_src, pel_t *dst, int i_dst, int width, int height, const char_t *coeff_h, const char_t *coeff_v, int max_val)
{
	int row, col;
	int sum, val;
	int add1, shift1;
	int add2, shift2;

	ALIGNED_16(i16s_t tmp_res[(48 + 5) * 48]);
	i16s_t *tmp;

	shift1 = 0;
	shift2 = 12;

	add1 = (1 << (shift1)) >> 1;
	add2 = 1 << (shift2 - 1);

	src += -2 * i_src;
	tmp = tmp_res;

	for (row = -2; row < height + 3; row++) {
		for (col = 0; col < width; col++) {
			tmp[col] = FLT_6TAP_HOR(src, col, coeff_h);
		}
		src += i_src;
		tmp += 48;
	}

	tmp = tmp_res + 2 * 48;

	for (row = 0; row < height; row++) {
		for (col = 0; col < width; col++) {
			sum = FLT_6TAP_VER(tmp, col, 48, coeff_v);
			val = (sum + add2) >> shift2;
			dst[col] = COM_CLIP3(0, max_val, val);
		}
		dst += i_dst;
		tmp += 48;
	}
}


static void com_if_filter_hor_ver_10(const pel_t *src, int i_src, pel_t *dst, int i_dst, int width, int height, const char_t *coeff_h, const char_t *coeff_v, int max_val)
{
	int row, col;
	int sum, val;
	int add1, shift1;
	int add2, shift2;

	ALIGNED_16(i16s_t tmp_res[(80 + 9) * 80]);
	i16s_t *tmp;

	shift1 = 0;
	shift2 = 12;

	add1 = (1 << (shift1)) >> 1;
	add2 = 1 << (shift2 - 1);

	src += -4 * i_src;
	tmp = tmp_res;

	for (row = -4; row < height + 5; row++) {
		for (col = 0; col < width; col++) {
			tmp[col] = FLT_10TAP_HOR(src, col, coeff_h);
		}
		src += i_src;
		tmp += 80;
	}

	tmp = tmp_res + 4 * 80;

	for (row = 0; row < height; row++) {
		for (col = 0; col < width; col++) {
			sum = FLT_10TAP_VER(tmp, col, 80, coeff_v);
			val = (sum + add2) >> shift2;
			dst[col] = COM_CLIP3(0, max_val, val);
		}
		dst += i_dst;
		tmp += 80;
	}
}

void get_block_adaptive(int pos_x, int pos_y, img_params *img, pel_t *pDst, int i_dst, unsigned char *ref_pic, int i_ref)
{
	int int_pos_x, int_pos_y;
	int sub_pos_x, sub_pos_y;
	int i_tmp = MAX_IF_BUF;
	pel_t *pSrc;
	int i_src = img->iStride;

	int tap, tap_min, tap_max;

	static const char_t COEF_4tap[3][4] =
	{
		{ -6, 56, 15, -1 },
		{ -4, 36, 36, -4 },
		{ -1, 15, 56, -6 }
	};

	static const char_t COEF_6tap[3][6] =
	{
		{ 2, -9, 57, 17, -4, 1 },
		{ 2, -9, 39, 39, -9, 2 },
		{ 1, -4, 17, 57, -9, 2 }
	};

	static const char_t COEF_10tap[3][10] =
	{
		{ 1, -2, 4, -10, 57, 19,  -7, 3, -1, 0 },
		{ 1, -2, 5, -12, 40, 40, -12, 5, -2, 1 },
		{ 0, -1, 3,  -7, 19, 57, -10, 4, -2, 1 }
	};

	char_t const *COEFs[3];
	char_t const *COEF_HOR, *COEF_VER;
	sub_pos_x = pos_x&3;
	sub_pos_y = pos_y&3;
	int_pos_x = (pos_x-sub_pos_x)/4;
	int_pos_y = (pos_y-sub_pos_y)/4;

	pSrc = ref_pic + int_pos_y * i_ref + int_pos_x;

	if(img->height >= 1600)//for UHD, 2560x1600
	{
		COEFs[0] = COEF_4tap[0];
		COEFs[1] = COEF_4tap[1];
		COEFs[2] = COEF_4tap[2];
		tap = 4;
	}
	else if(img->height >= 720)//for 720p and 1080p
	{
		COEFs[0] = COEF_6tap[0];
		COEFs[1] = COEF_6tap[1];
		COEFs[2] = COEF_6tap[2];
		tap = 6;
	}
	else
	{
		COEFs[0] = COEF_10tap[0];
		COEFs[1] = COEF_10tap[1];
		COEFs[2] = COEF_10tap[2];
		tap = 10;
	}

	tap_min = (tap>>1) -1;
	tap_max = (tap>>1) +1;

	//    A  a  b  c  B
	//    d  e  f  g
	//    h  i  j  k
	//    n  p  q  r
	//    C           D
	if (sub_pos_x == 0 && sub_pos_y == 0) {  //fullpel position: A
		g_funs_handle.ipcpy(pSrc, i_src, pDst, i_dst, B8_SIZE, B8_SIZE);
	}
	else{ /* other positions */
		COEF_HOR = COEFs[sub_pos_x - 1];
		COEF_VER = COEFs[sub_pos_y - 1];
		if(sub_pos_y==0){//horizonal  position: a,b,c
			if(tap == 4){
				g_funs_handle.ipflt[IPFILTER_H_4 ](pSrc, i_ref, pDst, i_dst, B8_SIZE, B8_SIZE, COEF_HOR, 255);
			}
			else if(tap == 6){
				g_funs_handle.ipflt[IPFILTER_H_6 ](pSrc, i_ref, pDst, i_dst, B8_SIZE, B8_SIZE, COEF_HOR, 255);
			}
			else if(tap == 10){
				g_funs_handle.ipflt[IPFILTER_H_10](pSrc, i_ref, pDst, i_dst, B8_SIZE, B8_SIZE, COEF_HOR, 255);
			}
		}
		else if(sub_pos_x==0){//vertical position: d,h,n
			if(tap == 4){
				g_funs_handle.ipflt[IPFILTER_V_4 ](pSrc, i_ref, pDst, i_dst, B8_SIZE, B8_SIZE, COEF_VER, 255);
			}
			else if(tap == 6){
				g_funs_handle.ipflt[IPFILTER_V_6 ](pSrc, i_ref, pDst, i_dst, B8_SIZE, B8_SIZE, COEF_VER, 255);
			}
			else if(tap == 10){
				g_funs_handle.ipflt[IPFILTER_V_10](pSrc, i_ref, pDst, i_dst, B8_SIZE, B8_SIZE, COEF_VER, 255);
			}
		}
		else{
			if(tap == 4){
				g_funs_handle.ipflt_EXT[IPFILTER_EXT_4 ](pSrc, i_ref, pDst, i_dst, B8_SIZE, B8_SIZE, COEF_HOR, COEF_VER, 255);
			}
			else if(tap == 6){
				g_funs_handle.ipflt_EXT[IPFILTER_EXT_6 ](pSrc, i_ref, pDst, i_dst, B8_SIZE, B8_SIZE, COEF_HOR, COEF_VER, 255);
			}
			else if(tap == 10){
				g_funs_handle.ipflt_EXT[IPFILTER_EXT_10 ](pSrc, i_ref, pDst, i_dst, B8_SIZE, B8_SIZE, COEF_HOR, COEF_VER, 255);
			}
		}
	}
}

void get_luma_block(int x_pos, int y_pos, img_params *img, pel_t *pDst, int i_dst, uchar_t *ref_pic, int i_ref)
{
	int dx, dy;
	int x, y;
	int i, j;
	int maxold_x,maxold_y;
	int result;
	int tmp_res[26][26];
	pel_t *pSrc;

	static const int COEF_HALF_8tap[8] = {
		-1, 4, -11, 40, 40, -11, 4, -1
	};
	static const int COEF_QUART1_8tap[8] = {
		-1, 4, -10, 57, 18, -6, 3, -1
	};
	static const int COEF_QUART3_8tap[8] = {
		-1, 3, -6, 18, 57, -10, 4, -1
	};

	static const int COEF_HALF_6tap[6] = {
		2, -9, 39, 39, -9, 2
	};
	static const int COEF_QUART1_6tap[6] = {
		2, -9, 57, 17, -4, 1
	};
	static const int COEF_QUART3_6tap[6] = {
		1, -4, 17, 57, -9, 2
	};

	if (if_type == 1) {
		get_block_adaptive(x_pos, y_pos, img, pDst, i_dst, ref_pic, i_ref);
		return;
	}
	//    A  a  b  c  B
	//    d  e  f  g
	//    h  i  j  k
	//    n  p  q  r
	//    C           D

	dx = x_pos&3;
	dy = y_pos&3;
	x_pos = (x_pos-dx)/4;
	y_pos = (y_pos-dy)/4;
	maxold_x = img->width-1;
	maxold_y = img->height-1;
	pSrc = ref_pic; // + y_pos * i_ref + x_pos;

	if (dx == 0 && dy == 0) { // integer position: A
		for (j = 0; j < B8_SIZE; j++){
			for (i = 0; i < B8_SIZE; i++){
				pDst[i] = *(pSrc+j*i_ref+i);
			}
			pDst += i_dst;
		}
	}
	else 
	{ /* other positions */
		if((dx==2) && (dy==0)){//horizonal 1/2 position: b
			for (j = 0; j < B8_SIZE; j++){
				for (i = 0; i < B8_SIZE; i++) {
					for (result = 0, x = -3; x < 5; x++) //-3~4
						result += (*(pSrc+j*i_ref+i))*COEF_HALF_8tap[x+3];
					pDst[i] = (pel_t)max(0, min(255, (result+32)/64));
				}
				pDst += i_dst;
			}
		}

		else if((dx==1) && (dy==0)){//horizonal 1/4 position: a
			for (j = 0; j < B8_SIZE; j++){
				for (i = 0; i < B8_SIZE; i++) {
					for (result = 0, x = -3; x < 5; x++) //-3~4
						result += (*(pSrc+j*i_ref+i))*COEF_QUART1_8tap[x+3];
					pDst[i] = (pel_t)max(0, min(255, (result+32)/64));
				}
				pDst += i_dst;
			}
		}

		else if((dx==3) && (dy==0)){//horizonal 3/4 position: a
			for (j = 0; j < B8_SIZE; j++){
				for (i = 0; i < B8_SIZE; i++) {
					for (result = 0, x = -3; x < 5; x++) //-3~4
						result += (*(pSrc+j*i_ref+i))*COEF_QUART3_8tap[x+3];
					pDst[i] = (pel_t)max(0, min(255, (result+32)/64));
				}
				pDst += i_dst;
			}
		}

		//vertical
		else if((dy==2) && (dx==0)){//vertical 1/2 position: h
			for (j = 0; j < B8_SIZE; j++) {
				for (i = 0; i < B8_SIZE; i++) {
					for (result = 0, y = -3; y < 5; y++)
						result += (*(pSrc+j*i_ref+i))*COEF_HALF_8tap[y+3];
					pDst[i] = (pel_t)max(0, min(255, (result+32)/64));
				}
				pDst += i_dst;
			}
		}

		else if((dy==1) && (dx==0)){//vertical 1/4 position: d
			for (j = 0; j < B8_SIZE; j++) {
				for (i = 0; i < B8_SIZE; i++) {
					for (result = 0, y = -3; y < 5; y++)
						result += (*(pSrc+j*i_ref+i))*COEF_QUART1_8tap[y+3];
					pDst[i] = (pel_t)max(0, min(255, (result+32)/64));
				}
				pDst += i_dst;
			}
		}

		else if((dy==3) && (dx==0)){//vertical 3/4 position: n
			for (j = 0; j < B8_SIZE; j++) {
				for (i = 0; i < B8_SIZE; i++) {
					for (result = 0, y = -3; y < 5; y++)
						result += (*(pSrc+j*i_ref+i))*COEF_QUART3_8tap[y+3];
					pDst[i] = (pel_t)max(0, min(255, (result+32)/64));
				}
				pDst += i_dst;
			}
		}

		//remaining 9 fractional-pel pixels
		//e,i,p
		else if((dx==1) && (dy==1)){//horizontal 1/4 and vertical 1/4 position: e
			for (j = -2; j < B8_SIZE+3; j++) {
				for (i = 0; i < B8_SIZE; i++) {
					for (result = 0, x = -3; x < 5; x++)
						result += (*(pSrc+j*i_ref+i))*COEF_QUART1_8tap[x+3];
					tmp_res[j+2][i] = result;
				}
			}
			for (j = 0; j < B8_SIZE; j++) {
				for (i = 0; i < B8_SIZE; i++) {
					for (result = 0, y = -2; y < 4; y++)
						result += tmp_res[j+y+2][i]*COEF_QUART1_6tap[y+2];
					pDst[i] = (pel_t)max(0, min(255, (result+2048)/4096));
				}
				pDst += i_dst;
			}
		}

		else if((dx==1) && (dy==2)){//horizontal 1/4 and vertical 1/2 position: i
			for (j = -2; j < B8_SIZE+3; j++) {
				for (i = 0; i < B8_SIZE; i++) {
					for (result = 0, x = -3; x < 5; x++)
						result += (*(pSrc+j*i_ref+i))*COEF_QUART1_8tap[x+3];
					tmp_res[j+2][i] = result;
				}
			}
			for (j = 0; j < B8_SIZE; j++) {
				for (i = 0; i < B8_SIZE; i++) {
					for (result = 0, y = -2; y < 4; y++)
						result += tmp_res[j+y+2][i]*COEF_HALF_6tap[y+2];
					pDst[i] = (pel_t)max(0, min(255, (result+2048)/4096));
				}
				pDst += i_dst;
			}
		}

		else if((dx==1) && (dy==3)){//horizontal 1/4 and vertical 3/4 position: p
			for (j = -2; j < B8_SIZE+3; j++) {
				for (i = 0; i < B8_SIZE; i++) {
					for (result = 0, x = -3; x < 5; x++)
						result += (*(pSrc+j*i_ref+i))*COEF_QUART1_8tap[x+3];
					tmp_res[j+2][i] = result;
				}
			}
			for (j = 0; j < B8_SIZE; j++) {
				for (i = 0; i < B8_SIZE; i++) {
					for (result = 0, y = -2; y < 4; y++)
						result += tmp_res[j+y+2][i]*COEF_QUART3_6tap[y+2];
					pDst[i] = (pel_t)max(0, min(255, (result+2048)/4096));
				}
				pDst += i_dst;
			}
		}

		//f,j,q
		else if((dx==2) && (dy==1)){//horizontal 1/2 and vertical 1/4 position: f
			for (j = -2; j < B8_SIZE+3; j++) {
				for (i = 0; i < B8_SIZE; i++) {
					for (result = 0, x = -3; x < 5; x++)
						result += (*(pSrc+j*i_ref+i))*COEF_HALF_8tap[x+3];
					tmp_res[j+2][i] = result;
				}
			}
			for (j = 0; j < B8_SIZE; j++) {
				for (i = 0; i < B8_SIZE; i++) {
					for (result = 0, y = -2; y < 4; y++)
						result += tmp_res[j+y+2][i]*COEF_QUART1_6tap[y+2];
					pDst[i] = (pel_t)max(0, min(255, (result+2048)/4096));
				}
				pDst += i_dst;
			}
		}

		else if((dx==2) && (dy==2)){//horizontal 1/4 and vertical 1/2 position: j
			for (j = -2; j < B8_SIZE+3; j++) {
				for (i = 0; i < B8_SIZE; i++) {
					for (result = 0, x = -3; x < 5; x++)
						result += (*(pSrc+j*i_ref+i))*COEF_HALF_8tap[x+3];
					tmp_res[j+2][i] = result;
				}
			}
			for (j = 0; j < B8_SIZE; j++) {
				for (i = 0; i < B8_SIZE; i++) {
					for (result = 0, y = -2; y < 4; y++)
						result += tmp_res[j+y+2][i]*COEF_HALF_6tap[y+2];
					pDst[i] = (pel_t)max(0, min(255, (result+2048)/4096));
				}
				pDst += i_dst;
			}
		}

		else if((dx==2) && (dy==3)){//horizontal 1/2 and vertical 3/4 position: q
			for (j = -2; j < B8_SIZE+3; j++) {
				for (i = 0; i < B8_SIZE; i++) {
					for (result = 0, x = -3; x < 5; x++)
						result += (*(pSrc+j*i_ref+i))*COEF_HALF_8tap[x+3];
					tmp_res[j+2][i] = result;
				}
			}
			for (j = 0; j < B8_SIZE; j++) {
				for (i = 0; i < B8_SIZE; i++) {
					for (result = 0, y = -2; y < 4; y++)
						result += tmp_res[j+y+2][i]*COEF_QUART3_6tap[y+2];
					pDst[i] = (pel_t)max(0, min(255, (result+2048)/4096));
				}
				pDst += i_dst;
			}
		}


		//g,k,r
		else if((dx==3) && (dy==1)){//horizontal 3/4 and vertical 1/4 position: g
			for (j = -2; j < B8_SIZE+3; j++) {
				for (i = 0; i < B8_SIZE; i++) {
					for (result = 0, x = -3; x < 5; x++)
						result += (*(pSrc+j*i_ref+i))*COEF_QUART3_8tap[x+3];
					tmp_res[j+2][i] = result;
				}
			}
			for (j = 0; j < B8_SIZE; j++) {
				for (i = 0; i < B8_SIZE; i++) {
					for (result = 0, y = -2; y < 4; y++)
						result += tmp_res[j+y+2][i]*COEF_QUART1_6tap[y+2];
					pDst[i] = (pel_t)max(0, min(255, (result+2048)/4096));
				}
				pDst += i_dst;
			}
		}

		else if((dx==3) && (dy==2)){//horizontal 3/4 and vertical 1/2 position: k
			for (j = -2; j < B8_SIZE+3; j++) {
				for (i = 0; i < B8_SIZE; i++) {
					for (result = 0, x = -3; x < 5; x++)
						result += (*(pSrc+j*i_ref+i))*COEF_QUART3_8tap[x+3];
					tmp_res[j+2][i] = result;
				}
			}
			for (j = 0; j < B8_SIZE; j++) {
				for (i = 0; i < B8_SIZE; i++) {
					for (result = 0, y = -2; y < 4; y++)
						result += tmp_res[j+y+2][i]*COEF_HALF_6tap[y+2];
					pDst[i] = (pel_t)max(0, min(255, (result+2048)/4096));
				}
				pDst += i_dst;
			}
		}

		else if((dx==3) && (dy==3)){//horizontal 3/4 and vertical 3/4 position: r
			for (j = -2; j < B8_SIZE+3; j++) {
				for (i = 0; i < B8_SIZE; i++) {
					for (result = 0, x = -3; x < 5; x++)
						result += (*(pSrc+j*i_ref+i))*COEF_QUART3_8tap[x+3];
					tmp_res[j+2][i] = result;
				}
			}
			for (j = 0; j < B8_SIZE; j++) {
				for (i = 0; i < B8_SIZE; i++) {
					for (result = 0, y = -2; y < 4; y++)
						result += tmp_res[j+y+2][i]*COEF_QUART3_6tap[y+2];
					pDst[i] = (pel_t)max(0, min(255, (result+2048)/4096));
				}
				pDst += i_dst;
			}
		}
	}
}

void get_chroma_subpix_Ext(const pel_t *pSrc, int i_ref, pel_t *pDst, int i_dst, const char_t *COEF_HOR, const char_t *COEF_VER)
{
	int val;
	const pel_t *pSrcTemp;
	int tmp[4], line;
	int col, row;

	for (row = 0; row < 4; row++) {
		for (col = 0; col < 4; col++) {
			for (line = -1; line < 3; line++) {
				pSrcTemp = pSrc + line *i_ref;
				tmp[line + 1] = FLT_4TAP_HOR(pSrcTemp, col, COEF_HOR);
			}
			val = (tmp[0] * COEF_VER[0] + tmp[1] * COEF_VER[1] + tmp[2] * COEF_VER[2] + tmp[3] * COEF_VER[3] + 32) >> 6;
			pDst[col] = (pel_t)Clip1((val + 32) >> 6);
		}

		pSrc += i_ref;
		pDst += i_dst;
	}

}

void get_chroma_block(pel_t *pDst, int i_dst, int mv_x, int mv_y, int posx, int posy, uchar_t *refpic, int i_ref)
{
	pel_t *pSrc;

	const char_t COEFs[8][4] = {
		{ 0, 64, 0, 0 },
		{ -4, 62, 6, 0 },
		{ -6, 56, 15, -1 },
		{ -5, 47, 25, -3 },
		{ -4, 36, 36, -4 },
		{ -3, 25, 47, -5 },
		{ -1, 15, 56, -6 },
		{ 0, 6, 62, -4 }
	};
	const char_t *COEF_VER = COEFs[posy];
	const char_t *COEF_HOR = COEFs[posx];

	pSrc = refpic + (mv_y>>3)*i_ref + (mv_x>>3);
	if (posy == 0) {
		//get_chroma_subpix_Hor(pSrc, i_ref, pDst, i_dst, COEF_HOR);
		g_funs_handle.ipflt[IPFILTER_H_4](pSrc, i_ref, pDst, i_dst, 4, 4, COEF_HOR, 255);
	}
	else if (posx == 0) {
		//get_chroma_subpix_Ver(pSrc, i_ref, pDst, i_dst, COEF_VER);
		g_funs_handle.ipflt[IPFILTER_V_4](pSrc, i_ref, pDst, i_dst, 4, 4, COEF_VER, 255);
	}
	else {
		//get_chroma_subpix_Ext(pSrc, i_ref, pDst, i_dst, COEF_HOR, COEF_VER);
		g_funs_handle.ipflt_chroma_subpix_EXT[IPFILTER_EXT_4](pSrc, i_ref, pDst, i_dst, COEF_HOR, COEF_VER);
	}
}

void com_funs_init_ip_filter()
{
	//g_funs_handle.ipcpy[IPFILTER_EXT_4] = com_if_filter_cpy;
	//g_funs_handle.ipcpy[IPFILTER_EXT_8] = com_if_filter_cpy;
	g_funs_handle.ipcpy = com_if_filter_cpy;
	g_funs_handle.ipflt[IPFILTER_H_4 ] = com_if_filter_hor_4;
	g_funs_handle.ipflt[IPFILTER_H_6 ] = com_if_filter_hor_6;
	g_funs_handle.ipflt[IPFILTER_H_10] = com_if_filter_hor_10;
	g_funs_handle.ipflt[IPFILTER_V_4 ] = com_if_filter_ver_4;
	g_funs_handle.ipflt[IPFILTER_V_6 ] = com_if_filter_ver_6;
	g_funs_handle.ipflt[IPFILTER_V_10] = com_if_filter_ver_10;

	g_funs_handle.ipflt_EXT[IPFILTER_EXT_4 ]  = com_if_filter_hor_ver_4;
	g_funs_handle.ipflt_EXT[IPFILTER_EXT_6 ]  = com_if_filter_hor_ver_6;
	g_funs_handle.ipflt_EXT[IPFILTER_EXT_10 ] = com_if_filter_hor_ver_10;

	g_funs_handle.ipflt_chroma_subpix_EXT[IPFILTER_EXT_4] = get_chroma_subpix_Ext;

	/*g_funs_handle.ipflt_EXT_H[IPFILTER_EXT_4 ] = com_if_filter_hor_ver_4_H;
	g_funs_handle.ipflt_EXT_H[IPFILTER_EXT_6 ] = com_if_filter_hor_ver_6_H;
	g_funs_handle.ipflt_EXT_H[IPFILTER_EXT_10] = com_if_filter_hor_ver_10_H;
	
	g_funs_handle.ipflt_EXT_V[IPFILTER_EXT_4 ] = com_if_filter_hor_ver_4_V;
	g_funs_handle.ipflt_EXT_V[IPFILTER_EXT_6 ] = com_if_filter_hor_ver_6_V;
	g_funs_handle.ipflt_EXT_V[IPFILTER_EXT_10] = com_if_filter_hor_ver_10_V;*/
}

void SetMotionVectorPredictor (img_params  *img,
							   int         *pmv_x,
							   int         *pmv_y,
							   int         ref_frame,
							   int         **refFrArr,
							   int         ***tmp_mv,
							   int         block_x,
							   int         block_y,
							   int         blockshape_x,
							   int         ref)
{
	int mb_x                 = 8*block_x;
	int mb_y                 = 8*block_y;
	int pic_block_x          = img->block_x + block_x;
	int pic_block_y          = img->block_y + block_y;
	int mb_width             = img->PicWidthInMbs;
	int mb_nr = img->current_mb_nr;
	int mb_available_up   = (img->mb_y == 0 ) ? 0 : (mb_data[mb_nr].slice_nr == mb_data[mb_nr-mb_width  ].slice_nr);  // jlzheng 6.23 
	int mb_available_left = (img->mb_x == 0 ) ? 0 : (mb_data[mb_nr].slice_nr == mb_data[mb_nr-1         ].slice_nr);  // jlzheng 6.23
	int mb_available_upleft  = (img->mb_x == 0) ? 0 : ((img->mb_y == 0) ? 0 : 
		(mb_data[mb_nr].slice_nr == mb_data[mb_nr-mb_width-1].slice_nr));
	int mb_available_upright = (img->mb_y == 0) ? 0 : ((img->mb_x >= (mb_width-1)) ? 0 :
		(mb_data[mb_nr].slice_nr == mb_data[mb_nr-mb_width+1].slice_nr));

	int block_available_up, block_available_left, block_available_upright, block_available_upleft;
	int mv_a, mv_b, mv_c, mv_d, pred_vec=0;
	int mvPredType, rFrameL, rFrameU, rFrameUR;
	int hv;
	int mva[3] , mvb[3],mvc[3];	
	/*Lou 1016 Start*/
	int rFrameUL;
	int smbtypecurr, smbtypeL, smbtypeU, smbtypeUL, smbtypeUR;


	smbtypecurr = -2;
	smbtypeL = -2;
	smbtypeU = -2;
	smbtypeUL = -2;
	smbtypeUR = -2;
	/*Lou 1016 End*/

	/* D B C */
	/* A X   */

	/* 1 A, B, D are set to 0 if unavailable       */
	/* 2 If C is not available it is replaced by D */

	block_available_up   = mb_available_up   || (mb_y > 0);
	block_available_left = mb_available_left || (mb_x > 0);

	if (mb_y > 0)
	{
		if (mb_x < 8)  // first column of 8x8 blocks
		{
			if (mb_y==8)
			{
				if (blockshape_x == 16)      block_available_upright = 0;
				else                         block_available_upright = 1;
			}
			else
			{
				if (mb_x+blockshape_x != 8)  block_available_upright = 1;
				else                         block_available_upright = 0;
			}
		}
		else
		{
			if (mb_x+blockshape_x != 16)   block_available_upright = 1;
			else                           block_available_upright = 0;
		}
	}
	else if (mb_x+blockshape_x != MB_SIZE)
	{
		block_available_upright = block_available_up;
	}
	else
	{
		block_available_upright = mb_available_upright;
	}

	if (mb_x > 0)
	{
		block_available_upleft = (mb_y > 0 ? 1 : mb_available_up);
	}
	else if (mb_y > 0)
	{
		block_available_upleft = mb_available_left;
	}
	else
	{
		block_available_upleft = mb_available_upleft;
	}

	smbtypecurr = -2;
	smbtypeL = -2;
	smbtypeU = -2;
	smbtypeUL = -2;
	smbtypeUR = -2;

	mvPredType = MVPRED_xy_MIN;//hlv 2012-11-20

	rFrameL    = block_available_left    ? refFrArr[pic_block_y]  [pic_block_x-1] : -1;
	rFrameU    = block_available_up      ? refFrArr[pic_block_y-1][pic_block_x]   : -1;
	rFrameUR   = block_available_upright ? refFrArr[pic_block_y-1][pic_block_x+blockshape_x/8] :
		block_available_upleft  ? refFrArr[pic_block_y-1][pic_block_x-1] : -1;
	rFrameUL   = block_available_upleft  ? refFrArr[pic_block_y-1][pic_block_x-1] : -1;

	if((rFrameL != -1)&&(rFrameU == -1)&&(rFrameUR == -1))
		mvPredType = MVPRED_L;
	else if((rFrameL == -1)&&(rFrameU != -1)&&(rFrameUR == -1))
		mvPredType = MVPRED_U;
	else if((rFrameL == -1)&&(rFrameU == -1)&&(rFrameUR != -1))
		mvPredType = MVPRED_UR;



	for (hv=0; hv < 2; hv++)
	{
		mva[hv] = mv_a = block_available_left    ? tmp_mv[4+pic_block_x-1             ][pic_block_y][hv] : 0;
		mvb[hv] = mv_b = block_available_up      ? tmp_mv[4+pic_block_x               ][pic_block_y-1][hv] : 0;
		mv_d    = block_available_upleft  ? tmp_mv[4+pic_block_x-1][pic_block_y-1][hv] : 0;
		mvc[hv] = mv_c = block_available_upright ? tmp_mv[4+pic_block_x+blockshape_x/8][pic_block_y-1][hv] : mv_d;
		//--- Yulj 2004.07.14
		// mv_a, mv_b... are not scaled.
		mva[hv] = scale_motion_vector(mva[hv], ref_frame, rFrameL, ref);
		mvb[hv] = scale_motion_vector(mvb[hv], ref_frame, rFrameU, ref);
		mv_d    = scale_motion_vector(mv_d, ref_frame, rFrameUL, ref);
		mvc[hv] = block_available_upright ? scale_motion_vector(mvc[hv], ref_frame, rFrameUR, ref): mv_d;


		switch (mvPredType)
		{
		case MVPRED_xy_MIN://hlv 2012-11-20

			if(hv == 1){

				//for x component
				if( ((mva[0]<0) && (mvb[0]>0) && (mvc[0]>0)) || (mva[0]>0) && (mvb[0]<0) && (mvc[0]<0) )
				{
					*pmv_x = (mvb[0] + mvc[0])/2;

				}
				else if( ((mvb[0]<0) && (mva[0]>0) && (mvc[0]>0))||((mvb[0]>0) && (mva[0]<0) && (mvc[0]<0)) )
				{
					*pmv_x = (mvc[0] + mva[0])/2;

				}
				else if( ((mvc[0]<0) && (mva[0]>0) && (mvb[0]>0))||((mvc[0]>0) && (mva[0]<0) && (mvb[0]<0)) )
				{
					*pmv_x = (mva[0] + mvb[0])/2;

				}
				else
				{
					// !! for Ax
					mva[2] = abs(mva[0] - mvb[0]);
					// !! for Bx
					mvb[2] = abs(mvb[0] - mvc[0]);
					// !! for Cx
					mvc[2] = abs(mvc[0] - mva[0]);

					pred_vec = min(mva[2],min(mvb[2],mvc[2]));

					if(pred_vec == mva[2]){
						*pmv_x = (mva[0] + mvb[0])/2;
					}
					else if(pred_vec == mvb[2]){
						*pmv_x = (mvb[0] + mvc[0])/2;
					}
					else{
						*pmv_x = (mvc[0] + mva[0])/2;
					}
				}

				//for y component
				if( ((mva[1]<0) && (mvb[1]>0) && (mvc[1]>0)) || (mva[1]>0) && (mvb[1]<0) && (mvc[1]<0) )
				{
					*pmv_y = (mvb[1] + mvc[1])/2;

				}
				else if( ((mvb[1]<0) && (mva[1]>0) && (mvc[1]>0))||((mvb[1]>0) && (mva[1]<0) && (mvc[1]<0)) )
				{
					*pmv_y = (mvc[1] + mva[1])/2;

				}
				else if( ((mvc[1]<0) && (mva[1]>0) && (mvb[1]>0))||((mvc[1]>0) && (mva[1]<0) && (mvb[1]<0)) )
				{
					*pmv_y = (mva[1] + mvb[1])/2;

				}
				else
				{
					// !! for Ay
					mva[2] =  abs(mva[1] - mvb[1]);
					// !! for By
					mvb[2] =  abs(mvb[1] - mvc[1]);
					// !! for Cy
					mvc[2] =  abs(mvc[1] - mva[1]);

					pred_vec = min(mva[2],min(mvb[2],mvc[2]));

					if(pred_vec == mva[2]){
						*pmv_y = (mva[1] + mvb[1])/2;
					}
					else if(pred_vec == mvb[2]){
						*pmv_y = (mvb[1] + mvc[1])/2;
					}
					else{
						*pmv_y = (mvc[1] + mva[1])/2;
					}
				}

			}
			break;

		case MVPRED_L:
			pred_vec = mv_a;
			break;
		case MVPRED_U:
			pred_vec = mv_b;
			break;
		case MVPRED_UR:
			pred_vec = mv_c;
			break;
		default:
			break;
		}


		if(mvPredType != MVPRED_xy_MIN){
			if (hv==0)
				*pmv_x = pred_vec;
			else
				*pmv_y = pred_vec;
		}
	}

}

void get_pred_mv(img_params *img, Macroblock *currMB, int b8, int bframe, int img_b8_x, int img_b8_y, int *vec1_x, int *vec1_y, int *vec2_x, int *vec2_y, int *refframe, int *fw_refframe, int *bw_refframe)
{
	int mv_mode;
	int pred_dir;
	int*** mv_array, ***fw_mv_array, ***bw_mv_array;
	int frame_no_next_P, frame_no_B, delta_P, delta_P_scale; 
	int iTRb, iTRp,iTRd;
	int hv;
	int	scale_refframe,iTRp1;

	int img_x = img_b8_x << 3;
	int img_y = img_b8_y << 3;
	int img_x_4 = img_x << 2;
	int img_y_4 = img_y << 2;

	mv_mode = currMB->b8mode[b8];
	pred_dir = currMB->b8pdir[b8];

	if (pred_dir != 2)
	{
		//===== FORWARD/BACKWARD PREDICTION =====
		if (!bframe)  // !! P MB
		{
			*refframe = refFrArr[img_b8_y][img_b8_x];
			mv_array = img->mv;
			*vec2_x = img_x_4 + img->bimv[img_b8_x + BLOCK_SIZE][img_b8_y][0];
			*vec2_y = img_y_4 + img->bimv[img_b8_x + BLOCK_SIZE][img_b8_y][1];
		}
		else if (!pred_dir)
		{
			*refframe = img->fw_refFrArr[img_b8_y][img_b8_x];
			mv_array = img->fw_mv;
		}
		else
		{
			*refframe = img->bw_refFrArr[img_b8_y][img_b8_x];
			mv_array = img->bw_mv;
		}

		if (bframe)
			*refframe = 0;
		*vec1_x = img_x_4 + mv_array[img_b8_x + BLOCK_SIZE][img_b8_y][0];
		*vec1_y = img_y_4 + mv_array[img_b8_x + BLOCK_SIZE][img_b8_y][1];
	}
	else  // !! pred_dir == 2 
	{
		if (mv_mode != 0){ //===== BI-DIRECTIONAL PREDICTION =====
			fw_mv_array = img->fw_mv;
			bw_mv_array = img->bw_mv;

			*fw_refframe = img->fw_refFrArr[img_b8_y][img_b8_x];
			*bw_refframe = img->bw_refFrArr[img_b8_y][img_b8_x];
		}
		else{ //===== DIRECT PREDICTION =====
			fw_mv_array = img->dfMV;
			bw_mv_array = img->dbMV;
			*bw_refframe = 0;

			if (refFrArr[img_b8_y][img_b8_x] == -1){ // next P is intra mode
				for (hv = 0; hv < 2; hv++)
				{
					img->dfMV[img_b8_x + BLOCK_SIZE][img_b8_y][hv] = img->dbMV[img_b8_x + BLOCK_SIZE][img_b8_y][hv] = 0;
					img->fw_mv[img_b8_x + BLOCK_SIZE][img_b8_y][hv] = img->bw_mv[img_b8_x + BLOCK_SIZE][img_b8_y][hv] = 0;
				}
				img->fw_refFrArr[img_b8_y][img_b8_x] = 0;
				img->bw_refFrArr[img_b8_y][img_b8_x] = 0;

				SetMotionVectorPredictor(img, &(img->fw_mv[img_b8_x + BLOCK_SIZE][img_b8_y][0]),
					&(img->fw_mv[img_b8_x + BLOCK_SIZE][img_b8_y][1]), 0, img->fw_refFrArr,
					img->fw_mv, 0, 0, 16, 0);
				SetMotionVectorPredictor(img, &(img->bw_mv[img_b8_x + BLOCK_SIZE][img_b8_y][0]),
					&(img->bw_mv[img_b8_x + BLOCK_SIZE][img_b8_y][1]), 0, img->bw_refFrArr,
					img->bw_mv, 0, 0, 16, -1);
				for (hv = 0; hv < 2; hv++)
				{
					img->dfMV[img_b8_x + BLOCK_SIZE][img_b8_y][hv] = img->fw_mv[img_b8_x + BLOCK_SIZE][img_b8_y][hv];
					img->dbMV[img_b8_x + BLOCK_SIZE][img_b8_y][hv] = img->bw_mv[img_b8_x + BLOCK_SIZE][img_b8_y][hv];
				}

				*fw_refframe = 0;
			}
			else // next P is skip or inter mode
			{
				*refframe = refFrArr[img_b8_y][img_b8_x];
				frame_no_next_P = 2 * img->imgtr_next_P;

				frame_no_B = 2 * img->pic_distance;
				delta_P = 2 * (img->imgtr_next_P - img->imgtr_last_P);
				delta_P = (delta_P + 512) % 512;
				delta_P_scale = 2 * (img->imgtr_next_P - img->imgtr_last_prev_P);
				delta_P_scale = (delta_P_scale + 512) % 512;

				iTRp = ((*refframe) + 1)*delta_P;
				iTRb = iTRp - (frame_no_next_P - frame_no_B);

				scale_refframe = 0;

				iTRp = (*refframe) == 0 ? delta_P : delta_P_scale;
				iTRp1 = scale_refframe == 0 ? delta_P : delta_P_scale;

				iTRd = frame_no_next_P - frame_no_B;
				iTRb = iTRp1 - (frame_no_next_P - frame_no_B);
				iTRp = (iTRp + 512) % 512;
				iTRp1 = (iTRp1 + 512) % 512;
				iTRd = (iTRd + 512) % 512;
				iTRb = (iTRb + 512) % 512;

				if (img->mv[img_b8_x + 4][img_b8_y][0] < 0)
				{
					img->dfMV[img_b8_x + BLOCK_SIZE][img_b8_y][0] = -(((16384 / iTRp)*(1 - iTRb*img->mv[img_b8_x + 4][img_b8_y][0]) - 1) >> 14);
					img->dbMV[img_b8_x + BLOCK_SIZE][img_b8_y][0] = ((16384 / iTRp)*(1 - iTRd*img->mv[img_b8_x + 4][img_b8_y][0]) - 1) >> 14;
				}
				else
				{
					img->dfMV[img_b8_x + BLOCK_SIZE][img_b8_y][0] = ((16384 / iTRp)*(1 + iTRb*img->mv[img_b8_x + 4][img_b8_y][0]) - 1) >> 14;
					img->dbMV[img_b8_x + BLOCK_SIZE][img_b8_y][0] = -(((16384 / iTRp)*(1 + iTRd*img->mv[img_b8_x + 4][img_b8_y][0]) - 1) >> 14);
				}

				if (img->mv[img_b8_x + 4][img_b8_y][1] < 0)
				{
					img->dfMV[img_b8_x + BLOCK_SIZE][img_b8_y][1] = -(((16384 / iTRp)*(1 - iTRb*img->mv[img_b8_x + 4][img_b8_y][1]) - 1) >> 14);
					img->dbMV[img_b8_x + BLOCK_SIZE][img_b8_y][1] = ((16384 / iTRp)*(1 - iTRd*img->mv[img_b8_x + 4][img_b8_y][1]) - 1) >> 14;
				}
				else
				{
					img->dfMV[img_b8_x + BLOCK_SIZE][img_b8_y][1] = ((16384 / iTRp)*(1 + iTRb*img->mv[img_b8_x + 4][img_b8_y][1]) - 1) >> 14;
					img->dbMV[img_b8_x + BLOCK_SIZE][img_b8_y][1] = -(((16384 / iTRp)*(1 + iTRd*img->mv[img_b8_x + 4][img_b8_y][1]) - 1) >> 14);
				}

				*fw_refframe = 0;  // DIRECT
				img->fw_refFrArr[img_b8_y][img_b8_x] = 0;

				img->fw_mv[img_b8_x + BLOCK_SIZE][img_b8_y][0] = img->dfMV[img_b8_x + BLOCK_SIZE][img_b8_y][0];
				img->fw_mv[img_b8_x + BLOCK_SIZE][img_b8_y][1] = img->dfMV[img_b8_x + BLOCK_SIZE][img_b8_y][1];
				img->bw_mv[img_b8_x + BLOCK_SIZE][img_b8_y][0] = img->dbMV[img_b8_x + BLOCK_SIZE][img_b8_y][0];
				img->bw_mv[img_b8_x + BLOCK_SIZE][img_b8_y][1] = img->dbMV[img_b8_x + BLOCK_SIZE][img_b8_y][1];

				img->bw_refFrArr[img_b8_y][img_b8_x] = 0;
			}
		}

		*vec1_x = img_x_4 + fw_mv_array[img_b8_x + BLOCK_SIZE][img_b8_y][0];
		*vec1_y = img_y_4 + fw_mv_array[img_b8_x + BLOCK_SIZE][img_b8_y][1];

		*vec2_x = img_x_4 + bw_mv_array[img_b8_x + BLOCK_SIZE][img_b8_y][0];
		*vec2_y = img_y_4 + bw_mv_array[img_b8_x + BLOCK_SIZE][img_b8_y][1];
	}
}


void get_chroma_mv_ref(img_params *img, Macroblock *currMB, int b8, int bframe, int img_b4_x, int img_b4_y, int *vec1_x, int *vec1_y, int *vec2_x, int *vec2_y, int *refframe, int *fw_refframe, int *bw_refframe)
{
	int mv_mode;
	int pred_dir;
	int*** mv_array, ***fw_mv_array, ***bw_mv_array;

	mv_mode  = currMB->b8mode[b8];
	pred_dir = currMB->b8pdir[b8];
	if (pred_dir != 2) {
		//--- FORWARD/BACKWARD PREDICTION ---
		if (!bframe){
			mv_array = img->mv;
			*vec2_y = img->bimv[img_b4_x+4][img_b4_y][1];
			*vec2_x = img->bimv[img_b4_x+4][img_b4_y][0];
			*refframe = refFrArr[img_b4_y][img_b4_x];
		}
		else if (!pred_dir){
			mv_array = img->fw_mv;
			*refframe = img->fw_refFrArr[img_b4_y][img_b4_x];
		}
		else{
			mv_array = img->bw_mv;
			*refframe = img->bw_refFrArr[img_b4_y][img_b4_x];
		}
		*vec1_y = mv_array[img_b4_x+4][img_b4_y][1];
		*vec1_x = mv_array[img_b4_x+4][img_b4_y][0];
	}
	else // !! bidirection prediction
	{
		if (mv_mode != 0){ //===== BI-DIRECTIONAL PREDICTION =====
			fw_mv_array = img->fw_mv;
			bw_mv_array = img->bw_mv;
			*fw_refframe = img->fw_refFrArr[img_b4_y][img_b4_x];
			*bw_refframe = img->bw_refFrArr[img_b4_y][img_b4_x];
		}
		else{ //===== DIRECT PREDICTION =====
			fw_mv_array = img->dfMV;
			bw_mv_array = img->dbMV;
			*fw_refframe = 0;
			*bw_refframe = 0;
		}
		*vec1_y = fw_mv_array[img_b4_x+4][img_b4_y][1];
		*vec1_x = fw_mv_array[img_b4_x+4][img_b4_y][0];
		*vec2_y = bw_mv_array[img_b4_x+4][img_b4_y][1];
		*vec2_x = bw_mv_array[img_b4_x+4][img_b4_y][0];
	}
}